using System;
using System.Collections.Generic;
using System.Linq;
using WenYu.Core.CodeGen;

namespace WenYu.Runtime
{
    /// <summary>
    /// 解释器 - 执行IR指令序列
    /// 
    /// 功能:
    /// - 逐条执行IR指令
    /// - 管理操作数栈
    /// - 处理变量存储和加载
    /// - 执行算术和比较运算
    /// 
    /// 对标需求: REQ-05 标准库接口
    /// </summary>
    public class Interpreter
    {
        /// <summary>执行上下文</summary>
        private readonly ExecutionContext _context;

        /// <summary>标准库实现</summary>
        private readonly IStandardLibrary _standardLibrary;

        /// <summary>符号表（用于获取类信息）</summary>
        private WenYu.Core.CodeGen.SymbolTable? _symbolTable;

        /// <summary>IR指令列表</summary>
        private List<IRInstruction> _instructions = new();

        /// <summary>是否启用调试输出</summary>
        public bool EnableDebug { get; set; } = false;

        // ===== 构造函数 =====

        /// <summary>创建解释器（使用默认青春版标准库）</summary>
        public Interpreter() : this(new YouthLibrary())
        {
        }

        /// <summary>创建解释器（使用指定的标准库）</summary>
        public Interpreter(IStandardLibrary standardLibrary)
        {
            _context = new ExecutionContext();
            _standardLibrary = standardLibrary ?? throw new ArgumentNullException(nameof(standardLibrary));
        }

        /// <summary>创建解释器（使用指定的执行上下文和标准库）</summary>
        public Interpreter(ExecutionContext context, IStandardLibrary standardLibrary)
        {
            _context = context ?? throw new ArgumentNullException(nameof(context));
            _standardLibrary = standardLibrary ?? throw new ArgumentNullException(nameof(standardLibrary));
        }

        // ===== 公共API =====

        /// <summary>
        /// 设置符号表（用于对象创建时获取类信息）
        /// </summary>
        public void SetSymbolTable(WenYu.Core.CodeGen.SymbolTable symbolTable)
        {
            _symbolTable = symbolTable;
        }

        /// <summary>
        /// 执行IR指令序列
        /// </summary>
        /// <exception cref="InvalidOperationException">指令执行错误</exception>
        public void Execute(List<IRInstruction> instructions)
        {
            if (instructions == null)
                throw new ArgumentNullException(nameof(instructions));

            _instructions = instructions;
            // 使用SoftReset保留全局变量，只重置执行状态
            _context.SoftReset();
            _context.InstructionPointer = 0;

            while (_context.IsRunning && _context.InstructionPointer < _instructions.Count)
            {
                var instruction = _instructions[_context.InstructionPointer];
                
                if (EnableDebug)
                    Debug($"执行指令 #{_context.InstructionPointer}: {instruction.Opcode}");

                ExecuteInstruction(instruction);
                _context.InstructionPointer++;
            }
        }

        /// <summary>
        /// 获取执行后的全局变量值
        /// </summary>
        public Value GetVariable(string varName)
        {
            return _context.GetVariable(varName);
        }

        /// <summary>
        /// 获取所有全局变量
        /// </summary>
        public IReadOnlyDictionary<string, Value> GetAllVariables()
        {
            return _context.GetAllGlobals();
        }

        /// <summary>
        /// 获取执行上下文(用于调试)
        /// </summary>
        public ExecutionContext GetContext()
        {
            return _context;
        }

        // ===== 私有指令执行 =====

        /// <summary>
        /// 执行单条指令
        /// </summary>
        private void ExecuteInstruction(IRInstruction instruction)
        {
            switch (instruction.Opcode)
            {
                // ===== 常量加载 (Load Constant) =====
                case IROpcode.Ldc_I4:
                    ExecuteLoadInt(instruction);
                    break;

                case IROpcode.Ldc_R8:
                    ExecuteLoadFloat(instruction);
                    break;

                case IROpcode.Ldstr:
                    ExecuteLoadString(instruction);
                    break;

                // ===== 变量操作 (Local Variable) =====
                case IROpcode.Ldloc:
                    ExecuteLoadVar(instruction);
                    break;

                case IROpcode.Stloc:
                    ExecuteStoreVar(instruction);
                    break;

                // ===== 算术运算 (Arithmetic) =====
                case IROpcode.Add:
                    ExecuteAdd();
                    break;

                case IROpcode.Sub:
                    ExecuteSub();
                    break;

                case IROpcode.Mul:
                    ExecuteMul();
                    break;

                case IROpcode.Div:
                    ExecuteDiv();
                    break;

                case IROpcode.Rem:
                    ExecuteMod();
                    break;

                // ===== 比较运算 (Comparison) =====
                case IROpcode.Ceq:
                    ExecuteEq();
                    break;

                case IROpcode.Cne:
                    ExecuteNe();
                    break;

                case IROpcode.Clt:
                    ExecuteLt();
                    break;

                case IROpcode.Cle:
                    ExecuteLe();
                    break;

                case IROpcode.Cgt:
                    ExecuteGt();
                    break;

                case IROpcode.Cge:
                    ExecuteGe();
                    break;

                // ===== 逻辑运算 (Logical) =====
                case IROpcode.And:
                    ExecuteAnd();
                    break;

                case IROpcode.Or:
                    ExecuteOr();
                    break;
                
                case IROpcode.Not:
                    ExecuteNot();
                    break;

                // ===== 栈操作 (Stack) =====
                case IROpcode.Pop:
                    ExecutePop();
                    break;

                case IROpcode.Dup:
                    ExecuteDup();
                    break;

                // ===== 输出 (Print) =====
                case IROpcode.Call_Print:
                    ExecutePrint(instruction);
                    break;

                // ===== 控制流 (Control Flow) =====
                case IROpcode.Br:
                    ExecuteJump(instruction);
                    break;
                
                case IROpcode.Brfalse:
                    ExecuteJumpIfFalse(instruction);
                    break;
                
                case IROpcode.Br_Break:
                    ExecuteBreak(instruction);
                    break;
                
                case IROpcode.Br_Continue:
                    ExecuteContinue(instruction);
                    break;

                // ===== 函数调用 (Method Call) =====
                case IROpcode.Call:
                    ExecuteCall(instruction);
                    break;

                case IROpcode.Ret:
                    ExecuteRet(instruction);
                    break;

                // ===== 数组操作 (Array) =====
                case IROpcode.Newarr:
                    ExecuteArrayNew(instruction);
                    break;

                case IROpcode.Ldelem:
                    ExecuteArrayGet(instruction);
                    break;

                case IROpcode.Stelem:
                    ExecuteArraySet(instruction);
                    break;

                // ===== 对象操作 (Object) =====
                case IROpcode.Newobj:
                    ExecuteObjectNew(instruction);
                    break;

                case IROpcode.Ldfld:
                    ExecuteGetField(instruction);
                    break;

                case IROpcode.Stfld:
                    ExecuteSetField(instruction);
                    break;

                default:
                    throw new NotSupportedException($"不支持的指令: {instruction.Opcode}");
            }
        }

        // ===== 指令实现 =====

        private void ExecuteLoadInt(IRInstruction instruction)
        {
            var value = (int)instruction.Operands[0];
            _context.PushOperand(new Value(value));
        }

        private void ExecuteLoadFloat(IRInstruction instruction)
        {
            var value = (double)instruction.Operands[0];
            _context.PushOperand(new Value(value));
        }

        private void ExecuteLoadString(IRInstruction instruction)
        {
            var value = (string)instruction.Operands[0];
            _context.PushOperand(new Value(value));
        }

        private void ExecuteLoadBool(IRInstruction instruction)
        {
            var value = (bool)instruction.Operands[0];
            _context.PushOperand(new Value(value));
        }

        private void ExecuteLoadVar(IRInstruction instruction)
        {
            var varName = (string)instruction.Operands[0];
            var value = _context.GetVariable(varName);
            _context.PushOperand(value);
        }

        private void ExecuteStoreVar(IRInstruction instruction)
        {
            var varName = (string)instruction.Operands[0];
            var value = _context.PopOperand();
            _context.SetVariable(varName, value);
        }

        // ===== 算术运算 =====

        private void ExecuteAdd()
        {
            var (left, right) = _context.PopTwoOperands();
            
            if (left.IsInteger && right.IsInteger)
            {
                _context.PushOperand(new Value(left.AsInteger() + right.AsInteger()));
            }
            else if (left.IsNumeric && right.IsNumeric)
            {
                double l = left.IsInteger ? left.AsInteger() : left.AsFloat();
                double r = right.IsInteger ? right.AsInteger() : right.AsFloat();
                _context.PushOperand(new Value(l + r));
            }
            else if (left.IsString || right.IsString)
            {
                // 字符串连接
                var result = left.ToString() + right.ToString();
                _context.PushOperand(new Value(result));
            }
            else
            {
                throw new InvalidOperationException($"不支持的加法操作: {left.Type} + {right.Type}");
            }
        }

        private void ExecuteSub()
        {
            var (left, right) = _context.PopTwoOperands();
            
            if (!left.IsNumeric || !right.IsNumeric)
                throw new InvalidOperationException($"减法需要数值操作数: {left.Type} - {right.Type}");

            double l = left.IsInteger ? left.AsInteger() : left.AsFloat();
            double r = right.IsInteger ? right.AsInteger() : right.AsFloat();
            
            var result = l - r;
            _context.PushOperand(left.IsInteger && right.IsInteger ? 
                new Value((int)result) : new Value(result));
        }

        private void ExecuteMul()
        {
            var (left, right) = _context.PopTwoOperands();

            if (!left.IsNumeric || !right.IsNumeric)
                throw new InvalidOperationException($"乘法需要数值操作数: {left.Type} * {right.Type}");

            double l = left.IsInteger ? left.AsInteger() : left.AsFloat();
            double r = right.IsInteger ? right.AsInteger() : right.AsFloat();

            var result = l * r;
            _context.PushOperand(left.IsInteger && right.IsInteger ?
                new Value((int)result) : new Value(result));
        }

        private void ExecuteDiv()
        {
            var (left, right) = _context.PopTwoOperands();

            if (!left.IsNumeric || !right.IsNumeric)
                throw new InvalidOperationException($"除法需要数值操作数: {left.Type} ÷ {right.Type}");

            double l = left.IsInteger ? left.AsInteger() : left.AsFloat();
            double r = right.IsInteger ? right.AsInteger() : right.AsFloat();

            if (Math.Abs(r) < double.Epsilon)
                throw new InvalidOperationException("除以零");

            var result = l / r;
            _context.PushOperand(new Value(result)); // 除法总是返回浮点
        }

        private void ExecuteMod()
        {
            var (left, right) = _context.PopTwoOperands();

            if (!left.IsInteger || !right.IsInteger)
                throw new InvalidOperationException($"取模需要整数操作数: {left.Type} % {right.Type}");

            int r = right.AsInteger();
            if (r == 0)
                throw new InvalidOperationException("取模除以零");

            _context.PushOperand(new Value(left.AsInteger() % r));
        }

        // ===== 比较运算 =====

        private void ExecuteEq()
        {
            var (left, right) = _context.PopTwoOperands();
            _context.PushOperand(new Value(left == right));
        }

        private void ExecuteNe()
        {
            var (left, right) = _context.PopTwoOperands();
            _context.PushOperand(new Value(left != right));
        }

        private void ExecuteLt()
        {
            var (left, right) = _context.PopTwoOperands();
            
            if (!left.IsNumeric || !right.IsNumeric)
                throw new InvalidOperationException($"比较需要数值操作数");

            double l = left.IsInteger ? left.AsInteger() : left.AsFloat();
            double r = right.IsInteger ? right.AsInteger() : right.AsFloat();
            
            _context.PushOperand(new Value(l < r));
        }

        private void ExecuteLe()
        {
            var (left, right) = _context.PopTwoOperands();

            if (!left.IsNumeric || !right.IsNumeric)
                throw new InvalidOperationException($"比较需要数值操作数");

            double l = left.IsInteger ? left.AsInteger() : left.AsFloat();
            double r = right.IsInteger ? right.AsInteger() : right.AsFloat();

            _context.PushOperand(new Value(l <= r));
        }

        private void ExecuteGt()
        {
            var (left, right) = _context.PopTwoOperands();

            if (!left.IsNumeric || !right.IsNumeric)
                throw new InvalidOperationException($"比较需要数值操作数");

            double l = left.IsInteger ? left.AsInteger() : left.AsFloat();
            double r = right.IsInteger ? right.AsInteger() : right.AsFloat();

            _context.PushOperand(new Value(l > r));
        }

        private void ExecuteGe()
        {
            var (left, right) = _context.PopTwoOperands();

            if (!left.IsNumeric || !right.IsNumeric)
                throw new InvalidOperationException($"比较需要数值操作数");

            double l = left.IsInteger ? left.AsInteger() : left.AsFloat();
            double r = right.IsInteger ? right.AsInteger() : right.AsFloat();

            _context.PushOperand(new Value(l >= r));
        }

        // ===== 逻辑运算 =====

        private void ExecuteAnd()
        {
            var (left, right) = _context.PopTwoOperands();
            var result = left.ToBoolean() && right.ToBoolean();
            _context.PushOperand(new Value(result));
        }

        private void ExecuteOr()
        {
            var (left, right) = _context.PopTwoOperands();
            var result = left.ToBoolean() || right.ToBoolean();
            _context.PushOperand(new Value(result));
        }
        
        private void ExecuteNot()
        {
            var value = _context.PopOperand();
            var result = !value.ToBoolean();
            _context.PushOperand(new Value(result));
        }

        // ===== 栈操作 =====

        private void ExecutePop()
        {
            _context.PopOperand();
        }

        private void ExecuteDup()
        {
            var value = _context.PeekOperand();
            _context.PushOperand(value);
        }

        // ===== 输出 =====

        private void ExecutePrint(IRInstruction instruction)
        {
            var count = (int)instruction.Operands[0];
            _standardLibrary.Print(_context, count);
        }

        // ===== 控制流 =====

        /// <summary>
        /// 执行无条件跳转指令
        /// </summary>
        private void ExecuteJump(IRInstruction instruction)
        {
            var targetAddress = (int)instruction.Operands[0];
            // -1 因为Execute方法会在循环末尾 InstructionPointer++
            _context.InstructionPointer = targetAddress - 1;
        }

        /// <summary>
        /// 执行条件假跳转指令 (栈顶为假时跳转)
        /// </summary>
        private void ExecuteJumpIfFalse(IRInstruction instruction)
        {
            var condition = _context.PopOperand().ToBoolean();
            var targetAddress = (int)instruction.Operands[0];
            
            if (!condition)
            {
                _context.InstructionPointer = targetAddress - 1;
            }
        }
        
        /// <summary>
        /// 执行break指令 - 跳出循环
        /// </summary>
        private void ExecuteBreak(IRInstruction instruction)
        {
            var targetAddress = (int)instruction.Operands[0];
            // -1 因为Execute方法会在循环末尾 InstructionPointer++
            _context.InstructionPointer = targetAddress - 1;
        }
        
        /// <summary>
        /// 执行continue指令 - 继续循环
        /// </summary>
        private void ExecuteContinue(IRInstruction instruction)
        {
            var targetAddress = (int)instruction.Operands[0];
            // -1 因为Execute方法会在循环末尾 InstructionPointer++
            _context.InstructionPointer = targetAddress - 1;
        }

        // ===== 函数调用 =====

        /// <summary>
        /// 执行函数调用指令
        /// CALL entryAddress argCount
        /// 操作数: [0]=函数入口地址, [1]=参数个数
        /// </summary>
        private void ExecuteCall(IRInstruction instruction)
        {
            // 检查是否为内置函数调用（第一个操作数是字符串）
            if (instruction.Operands.Length > 0 && instruction.Operands[0] is string funcName && funcName.StartsWith("内置_"))
            {
                HandleBuiltinFunction(funcName, instruction);
                return;
            }
            
            // 普通函数调用：需要至少2个操作数
            if (instruction.Operands.Length < 2)
            {
                throw new InvalidOperationException("函数调用指令需要至少2个操作数(入口地址和参数个数)");
            }
            
            var entryAddress = (int)instruction.Operands[0];
            var argCount = (int)instruction.Operands[1];
            
            // 创建新的栈帧
            var frame = new StackFrame($"func@{entryAddress}", _context.CallStackDepth);
            // 保存返回地址(下一条指令)
            frame.ReturnAddress = _context.InstructionPointer + 1;
            
            // 从操作数栈中弹出参数并存储为局部变量
            // 参数按从右到左的顺序压栈,所以需要反向弹出
            var args = new Value[argCount];
            for (int i = argCount - 1; i >= 0; i--)
            {
                args[i] = _context.PopOperand();
            }
            
            // 将参数存储为局部变量 arg0, arg1, arg2...
            for (int i = 0; i < argCount; i++)
            {
                frame.SetLocal($"arg{i}", args[i]);
            }
            
            // 压入栈帧
            _context.PushFrame(frame);
            
            // 跳转到函数入口地址
            // -1 因为Execute方法会在循环末尾 InstructionPointer++
            _context.InstructionPointer = entryAddress - 1;
        }
        
        /// <summary>
        /// 处理内置函数调用
        /// </summary>
        private void HandleBuiltinFunction(string funcName, IRInstruction instruction)
        {
            switch (funcName)
            {
                case "内置_文字转换":
                    // 将栈顶值转换为字符串
                    var value = _context.PopOperand();
                    var stringValue = _standardLibrary.ToString(value);
                    _context.PushOperand(stringValue);
                    break;
                
                case "内置_长度":
                    // 获取数组或字符串的长度
                    var obj = _context.PopOperand();
                    if (obj.IsArray)
                    {
                        var array = obj.AsArray();
                        _context.PushOperand(new Value(array.Count));
                    }
                    else if (obj.IsString)
                    {
                        var str = obj.AsString();
                        _context.PushOperand(new Value(str.Length));
                    }
                    else
                    {
                        throw new InvalidOperationException($"长度操作不支持 {obj.Type} 类型");
                    }
                    break;
                
                case "内置_反转":
                    // 反转字符串或数组
                    var reverseObj = _context.PopOperand();
                    if (reverseObj.IsString)
                    {
                        var str = reverseObj.AsString();
                        var reversed = new string(str.Reverse().ToArray());
                        _context.PushOperand(new Value(reversed));
                    }
                    else if (reverseObj.IsArray)
                    {
                        var arr = reverseObj.AsArray();
                        var reversedList = new List<Value>(arr);
                        reversedList.Reverse();
                        _context.PushOperand(new Value(reversedList));
                    }
                    else
                    {
                        throw new InvalidOperationException($"反转操作不支持 {reverseObj.Type} 类型");
                    }
                    break;
                
                case "内置_大写":
                    // 字符串转大写
                    var upperObj = _context.PopOperand();
                    if (!upperObj.IsString)
                    {
                        throw new InvalidOperationException($"大写操作仅支持字符串类型，当前类型是 {upperObj.Type}");
                    }
                    _context.PushOperand(new Value(upperObj.AsString().ToUpper()));
                    break;
                
                case "内置_小写":
                    // 字符串转小写
                    var lowerObj = _context.PopOperand();
                    if (!lowerObj.IsString)
                    {
                        throw new InvalidOperationException($"小写操作仅支持字符串类型，当前类型是 {lowerObj.Type}");
                    }
                    _context.PushOperand(new Value(lowerObj.AsString().ToLower()));
                    break;
                
                case "内置_首元素":
                    // 获取数组首元素
                    var firstObj = _context.PopOperand();
                    if (!firstObj.IsArray)
                    {
                        throw new InvalidOperationException($"首元素操作仅支持数组类型，当前类型是 {firstObj.Type}");
                    }
                    var firstArr = firstObj.AsArray();
                    if (firstArr.Count == 0)
                    {
                        throw new InvalidOperationException("不能获取空数组的首元素");
                    }
                    _context.PushOperand(firstArr[0]);
                    break;
                
                case "内置_确认":
                    // 确认函数 - 显示提示并等待用户输入是/否
                    var confirmPrompt = _context.PopOperand();
                    if (!confirmPrompt.IsString)
                    {
                        throw new InvalidOperationException($"确认函数的提示参数必须是字符串，当前类型是 {confirmPrompt.Type}");
                    }
                    var confirmResult = _standardLibrary.Confirm(confirmPrompt.AsString());
                    _context.PushOperand(confirmResult);
                    break;
                
                case "内置_输入带提示":
                    // 输入带提示 - 显示提示信息后等待用户输入
                    var readPrompt = _context.PopOperand();
                    if (!readPrompt.IsString)
                    {
                        throw new InvalidOperationException($"输入带提示函数的提示参数必须是字符串，当前类型是 {readPrompt.Type}");
                    }
                    var readResult = _standardLibrary.ReadWithPrompt(readPrompt.AsString());
                    _context.PushOperand(readResult);
                    break;
                
                case "内置_输入带默认值":
                    // 输入带默认值 - 如果用户直接回车则使用默认值
                    var defaultValue = _context.PopOperand();
                    var defaultResult = _standardLibrary.ReadWithDefault(defaultValue);
                    _context.PushOperand(defaultResult);
                    break;
                
                case "内置_尾元素":
                    // 获取数组尾元素
                    var lastObj = _context.PopOperand();
                    if (!lastObj.IsArray)
                    {
                        throw new InvalidOperationException($"尾元素操作仅支持数组类型，当前类型是 {lastObj.Type}");
                    }
                    var lastArr = lastObj.AsArray();
                    if (lastArr.Count == 0)
                    {
                        throw new InvalidOperationException("不能获取空数组的尾元素");
                    }
                    _context.PushOperand(lastArr[lastArr.Count - 1]);
                    break;
                
                // ===== 数学函数 =====
                
                case "内置_绝对值":
                    // 绝对值函数
                    var absVal = _context.PopOperand();
                    if (absVal.IsInteger)
                    {
                        _context.PushOperand(new Value(Math.Abs(absVal.AsInteger())));
                    }
                    else if (absVal.IsFloat)
                    {
                        _context.PushOperand(new Value(Math.Abs(absVal.AsFloat())));
                    }
                    else
                    {
                        throw new InvalidOperationException($"绝对值函数仅支持数值类型，当前类型是 {absVal.Type}");
                    }
                    break;
                
                case "内置_最大值":
                    // 最大值函数（接受多个参数）
                    var maxCount = (int)instruction.Operands[1];
                    if (maxCount < 1)
                    {
                        throw new InvalidOperationException("最大值函数至少需要1个参数");
                    }
                    var maxValues = new List<Value>();
                    for (int i = 0; i < maxCount; i++)
                    {
                        maxValues.Insert(0, _context.PopOperand());
                    }
                    double maxResult = double.MinValue;
                    foreach (var val in maxValues)
                    {
                        double num = val.IsInteger ? val.AsInteger() : val.AsFloat();
                        if (num > maxResult) maxResult = num;
                    }
                    _context.PushOperand(new Value(maxResult));
                    break;
                
                case "内置_最小值":
                    // 最小值函数（接受多个参数）
                    var minCount = (int)instruction.Operands[1];
                    if (minCount < 1)
                    {
                        throw new InvalidOperationException("最小值函数至少需要1个参数");
                    }
                    var minValues = new List<Value>();
                    for (int i = 0; i < minCount; i++)
                    {
                        minValues.Insert(0, _context.PopOperand());
                    }
                    double minResult = double.MaxValue;
                    foreach (var val in minValues)
                    {
                        double num = val.IsInteger ? val.AsInteger() : val.AsFloat();
                        if (num < minResult) minResult = num;
                    }
                    _context.PushOperand(new Value(minResult));
                    break;
                
                case "内置_幂":
                    // 幂运算（底数，指数）
                    var exponent = _context.PopOperand();
                    var baseNum = _context.PopOperand();
                    double baseVal = baseNum.IsInteger ? baseNum.AsInteger() : baseNum.AsFloat();
                    double expVal = exponent.IsInteger ? exponent.AsInteger() : exponent.AsFloat();
                    _context.PushOperand(new Value(Math.Pow(baseVal, expVal)));
                    break;
                
                case "内置_平方根":
                    // 平方根
                    var sqrtVal = _context.PopOperand();
                    double sqrtNum = sqrtVal.IsInteger ? sqrtVal.AsInteger() : sqrtVal.AsFloat();
                    if (sqrtNum < 0)
                    {
                        throw new InvalidOperationException("不能对负数求平方根");
                    }
                    _context.PushOperand(new Value(Math.Sqrt(sqrtNum)));
                    break;
                
                case "内置_向上取整":
                    // 向上取整
                    var ceilVal = _context.PopOperand();
                    double ceilNum = ceilVal.IsInteger ? ceilVal.AsInteger() : ceilVal.AsFloat();
                    _context.PushOperand(new Value((int)Math.Ceiling(ceilNum)));
                    break;
                
                case "内置_向下取整":
                    // 向下取整
                    var floorVal = _context.PopOperand();
                    double floorNum = floorVal.IsInteger ? floorVal.AsInteger() : floorVal.AsFloat();
                    _context.PushOperand(new Value((int)Math.Floor(floorNum)));
                    break;
                
                default:
                    throw new InvalidOperationException($"未知的内置函数: {funcName}");
            }
        }

        /// <summary>
        /// 执行函数返回指令
        /// RET - 从当前函数返回
        /// </summary>
        private void ExecuteRet(IRInstruction instruction)
        {
            // 弹出当前栈帧
            if (_context.CallStackDepth == 0)
            {
                // 如果没有栈帧,说明是主程序返回,停止执行
                _context.Stop();
                return;
            }
            
            var frame = _context.PopFrame();
            
            // 如果操作数栈顶有值,作为返回值
            if (_context.OperandStackSize > 0)
            {
                _context.LastReturnValue = _context.PeekOperand();
            }
            
            // 恢复返回地址
            // -1 因为Execute方法会在循环末尾 InstructionPointer++
            _context.InstructionPointer = frame.ReturnAddress - 1;
        }

        // ===== 数组操作 =====

        private void ExecuteArrayNew(IRInstruction instruction)
        {
            var size = (int)instruction.Operands[0];
            var elements = new List<Value>();
            
            // 从栈顶弹出size个元素（倒序）
            for (int i = 0; i < size; i++)
            {
                elements.Insert(0, _context.PopOperand());
            }
            
            // 创建数组并压回栈
            _context.PushOperand(new Value(elements));
        }

        private void ExecuteArrayGet(IRInstruction instruction)
        {
            var indexValue = _context.PopOperand();
            var index = indexValue.IsInteger ? indexValue.AsInteger() : (int)indexValue.AsFloat();
            var arrayValue = _context.PopOperand();
            var array = arrayValue.AsArray();
            _context.PushOperand(array[index]);
        }

        private void ExecuteArraySet(IRInstruction instruction)
        {
            // 栈顶顺序: 值 -> 索引 -> 数组
            var value = _context.PopOperand();
            var indexValue = _context.PopOperand();
            var index = indexValue.IsInteger ? indexValue.AsInteger() : (int)indexValue.AsFloat();
            var arrayValue = _context.PopOperand();
            var array = arrayValue.AsArray();
            array[index] = value;
            // 不需要压回，赋值语句没有返回值
        }

        // ===== 对象操作 (P4新增) =====

        /// <summary>执行对象创建指令</summary>
        private void ExecuteObjectNew(IRInstruction instruction)
        {
            var className = (string)instruction.Operands[0];
            
            // 从SymbolTable获取类信息
            if (_symbolTable == null)
            {
                throw new InvalidOperationException("符号表未设置，无法创建对象。请在执行前调用SetSymbolTable");
            }
            var classInfo = _symbolTable.GetClass(className);
            
            // 创建对象字段字典，并初始化为默认值
            var fields = new Dictionary<string, Value>();
            foreach (var field in classInfo.Fields)
            {
                var fieldName = field.Key;
                var fieldType = field.Value;
                
                // 使用默认值或类型默认值
                if (classInfo.FieldDefaults.TryGetValue(fieldName, out var defaultValue) && defaultValue != null)
                {
                    // 从字面量默认值创建Value
                    if (defaultValue is int intVal)
                        fields[fieldName] = new Value(intVal);
                    else if (defaultValue is double doubleVal)
                        fields[fieldName] = new Value(doubleVal);
                    else if (defaultValue is string strVal)
                        fields[fieldName] = new Value(strVal);
                    else if (defaultValue is bool boolVal)
                        fields[fieldName] = new Value(boolVal);
                    else
                        fields[fieldName] = GetDefaultValueForType(fieldType);
                }
                else
                {
                    fields[fieldName] = GetDefaultValueForType(fieldType);
                }
            }
            
            // 创建对象Value并压入栈
            var objectValue = new Value(fields, className);
            _context.PushOperand(objectValue);
        }

        /// <summary>获取类型的默认值</summary>
        private Value GetDefaultValueForType(string typeName)
        {
            return typeName switch
            {
                "整型" => new Value(0),
                "实型" => new Value(0.0),
                "文字" => new Value(""),
                "真假" => new Value(false),
                _ => new Value(0) // 其他类型暂时返回0
            };
        }

        /// <summary>执行获取字段指令</summary>
        private void ExecuteGetField(IRInstruction instruction)
        {
            var fieldName = (string)instruction.Operands[0];
            var objectValue = _context.PopOperand();
            
            if (!objectValue.IsObject)
            {
                throw new InvalidOperationException($"无法从 {objectValue.Type} 获取字段");
            }
            
            var fieldValue = objectValue.GetField(fieldName);
            _context.PushOperand(fieldValue);
        }

        /// <summary>执行设置字段指令</summary>
        private void ExecuteSetField(IRInstruction instruction)
        {
            var fieldName = (string)instruction.Operands[0];
            // 栈顶顺序: 值 -> 对象
            var value = _context.PopOperand();
            var objectValue = _context.PopOperand();
            
            if (!objectValue.IsObject)
            {
                throw new InvalidOperationException($"无法设置 {objectValue.Type} 的字段");
            }
            
            objectValue.SetField(fieldName, value);
            // 不需要压回，赋值语句没有返回值
        }

        // ===== 调试 =====

        private void Debug(string message)
        {
            if (EnableDebug)
                Console.WriteLine($"[DEBUG] {message}");
        }
    }
}
